#include <stdio.h>
#include <string.h>
#include <assert.h>

// struct Test
// {
//     int Num;
//     char *pcName;
//     short sDate;
//     char cha[2];
//     short sba[4];
// };
// int main()
// {
//     struct Test *p = (struct Test *)0x1000000;
//     printf("%d\n", sizeof(struct Test));
//     printf("%p\n", p + 0x1);
//     printf("%p\n", (unsigned int *)p + 0x1);
//     printf("%p\n", (unsigned long *)p + 0x1);
//     return 0;
// }

// int main()
// {
//     int a[4] = {1, 2, 3, 4};
//     int *ptr1 = (int *)(&a + 1);
//     int *ptr2 = (int *)((int)a + 1);
//     printf("%x %x", ptr1[-1], *ptr2);
//     return 0;
// }

// int main()
// {
//     int a[3][2] = {(0, 1), (2, 3), (4, 5)};
//     int *p = a[0];
//     printf("%d\n", p);
//     printf("%d\n", &a[0][0]);
//     printf("%d\n", p + 1);
//     printf("%d\n", &a[0][0] + 1);
//     printf("%d", p[0]);
//     printf("%p", 4);
//     return 0;
// }

// strlen库函数，用来求字符串长度的
// 本质上是求字符串中\0之前的字符个数
// 返回值是size_t是无符号整型

// int main()
// {
//     const char *str = "abcdef";
//     size_t len1 = strlen("abcdef");
//     size_t len2 = strlen(str);
//     printf("%zu\n", len1);
//     printf("%zu\n", len2);
//     return 0;
// }

// int main()
// {
//     //两个无符号数相减得到的还是无符号数
//     if (strlen("abc") - strlen("abcdef") > 0)
//     {
//         //10000000000000000000000000000011
//         //11111111111111111111111111111100
//         //11111111111111111111111111111101
//         printf(">=\n");
//     }
//     else
//     {
//         printf("<\n");
//     }
//     return 0;
// }

// strlen函数的模拟实现
// 1.计数器
// 2.递归
// 3.指针-指针

// 源字符串必须以'\0'结束，否则会越界访问报错
// 会将源字符串中的'\0'拷贝到目标空间
// 目标空间必须足够大，以确保能存放源字符串
// 目标空间必须可变,目标空间不能是常量字符串，不能是const修饰的数组

size_t My_Strlen1(const char *str)
{
    assert(str);
    size_t count = 0;
    while (*str != '\0')
    {
        ++count;
        ++str;
    }
    return count;
}

size_t My_Strlen2(const char *str)
{
    assert(str);
    if (*str == '\0')
    {
        return 0;
    }
    return My_Strlen2(++str) + 1;
}

size_t My_Strlen3(const char *str)
{
    assert(str);
    const char *head = str;
    while (*str != '\0')
    {
        ++str;
    }
    size_t ret = str - head;
    return ret;
}

// void test()
// {
//     char *str = "abcdef";
//     // size_t ret = My_Strlen1(str);
//     // size_t ret = My_Strlen2(str);
//     size_t ret = My_Strlen3(str);
//     printf("%zu\n", ret);
// }
// int main()
// {
//     test();
// }

// 库函数strcpy
//  源字符串必须以'\0'结束，否则会越界访问报错
//  会将源字符串中的'\0'拷贝到目标空间
//  目标空间必须足够大，以确保能存放源字符串
//  目标空间必须可变,目标空间不能是常量字符串，不能是const修饰的数组

// strcpy的模拟实现
// 返回值是目标空间的起始地追
char *My_strcpy(char *dest, const char *src)
{
    assert(dest && src);
    char *head = dest;
    while (*src != '\0')
    {
        *dest++ = *src++;
    }
    *dest = '\0';
    return head;
}
int main()
{
    char str1[] = "acbdef";
    char str2[20] = {0};
    // stpcpy(str2, str1);
    My_strcpy(str2, str1);
    printf("%s\n", str2);
    return 0;
}